import axios from 'axios';

const API_URL = 'http://localhost:3000/api/models';

// 检查是否使用模拟API模式
const useMockApi = false; // 使用真实API

// 控制台打印API模式
console.log('文件服务正在使用' + (useMockApi ? '模拟API' : '真实API') + '模式');

// 模拟文件存储
const mockFileStorage = new Map();

// 创建外部模型
const createExternalModel = async (modelData) => {
    try {
        console.log('[fileService] 创建外部模型，数据:', modelData);

        if (useMockApi) {
            console.log('[fileService] 使用模拟API创建外部模型');

            // 模拟延迟
            await new Promise(resolve => setTimeout(resolve, 800));

            // 生成模型ID
            const modelId = `external-${Date.now()}`;

            // 返回模拟响应
            return {
                status: 201,
                data: {
                    status: 201,
                    data: {
                        model: {
                            id: modelId,
                            name: modelData.name,
                            description: modelData.description,
                            geometry: {
                                type: 'external_model',
                                color: modelData.color,
                                position: modelData.position,
                                rotation: modelData.rotation,
                                scale: modelData.scale
                            }
                        }
                    }
                }
            };
        }

        // 实际API调用
        console.log('[fileService] 准备调用真实API创建外部模型');
        const token = localStorage.getItem('token');
        const response = await axios.post(`${API_URL}/external`, modelData, {
            headers: {
                'Content-Type': 'application/json',
                'Authorization': token ? `Bearer ${token}` : undefined
            }
        });
        console.log('[fileService] 真实API创建外部模型成功，响应:', response);
        return response;
    } catch (error) {
        console.error('[fileService] 创建外部模型失败:', error);
        throw error.response?.data || error;
    }
};

// 上传模型文件
const uploadModelFile = async (modelId, file) => {
    try {
        if (useMockApi) {
            console.log('使用模拟API上传文件:', modelId, file.name);

            // 模拟延迟
            await new Promise(resolve => setTimeout(resolve, 1000));

            // 生成文件URL
            const fileUrl = `http://localhost:3000/storage/models/${modelId}/${file.name}`;

            // 在模拟存储中保存文件数据
            if (file instanceof Blob) {
                try {
                    // 读取文件内容(用于在内存中模拟)
                    const fileData = await new Promise((resolve, reject) => {
                        const reader = new FileReader();
                        reader.onload = () => resolve(reader.result);
                        reader.onerror = reject;
                        reader.readAsDataURL(file);
                    });

                    // 存储文件数据
                    mockFileStorage.set(fileUrl, {
                        data: fileData,
                        name: file.name,
                        type: file.type,
                        size: file.size,
                        lastModified: file.lastModified,
                        uploadTime: Date.now()
                    });

                    console.log(`文件 ${file.name} 已存储在模拟存储中，URL: ${fileUrl}`);
                } catch (e) {
                    console.error('读取或存储文件数据失败:', e);
                }
            }

            // 返回模拟上传结果
            return {
                status: 200,
                data: {
                    status: 200,
                    data: {
                        fileId: modelId,
                        fileName: file.name,
                        fileUrl: fileUrl,
                        fileSize: file.size
                    }
                }
            };
        }

        // 实际API调用
        const formData = new FormData();
        formData.append('file', file);

        const token = localStorage.getItem('token');
        const response = await axios.post(
            `${API_URL}/${modelId}/upload`,
            formData,
            {
                headers: {
                    'Content-Type': 'multipart/form-data',
                    'Authorization': token ? `Bearer ${token}` : undefined
                }
            }
        );

        return response;
    } catch (error) {
        console.error('上传模型文件失败:', error);
        throw error.response?.data || error;
    }
};

// 一步完成创建和上传外部模型
const createAndUploadExternalModel = async (modelData, file) => {
    try {
        if (useMockApi) {
            console.log('使用模拟API一步创建和上传外部模型');

            // 模拟延迟
            await new Promise(resolve => setTimeout(resolve, 1200));

            // 生成模型ID
            const modelId = `external-${Date.now()}`;

            // 生成文件URL
            const fileUrl = `http://localhost:3000/storage/models/${modelId}/${file.name}`;

            // 在模拟存储中保存文件
            if (file instanceof Blob) {
                try {
                    const fileData = await new Promise((resolve, reject) => {
                        const reader = new FileReader();
                        reader.onload = () => resolve(reader.result);
                        reader.onerror = reject;
                        reader.readAsDataURL(file);
                    });

                    mockFileStorage.set(fileUrl, {
                        data: fileData,
                        name: file.name,
                        type: file.type,
                        size: file.size,
                        lastModified: file.lastModified,
                        uploadTime: Date.now()
                    });
                } catch (e) {
                    console.error('读取或存储文件数据失败:', e);
                }
            }

            // 返回模拟响应
            return {
                status: 201,
                data: {
                    status: 201,
                    data: {
                        model: {
                            id: modelId,
                            name: modelData.name,
                            description: modelData.description,
                            geometry: {
                                type: 'external_model',
                                color: modelData.color,
                                file: file.name,
                                fileUrl: fileUrl,
                                position: modelData.position || { x: 0, y: 0, z: 0 },
                                rotation: modelData.rotation || { x: 0, y: 0, z: 0 },
                                scale: modelData.scale || { x: 1, y: 1, z: 1 }
                            }
                        },
                        file: {
                            fileId: modelId,
                            fileName: file.name,
                            fileUrl: fileUrl
                        }
                    }
                }
            };
        }

        // 实际API调用
        const formData = new FormData();

        // 添加模型数据，保持一致性
        formData.append('modelData', JSON.stringify(modelData));

        // 添加文件
        formData.append('file', file);

        // 添加详细元数据，确保与后端API期望格式匹配
        if (modelData.metadata) {
            formData.append('metadata', JSON.stringify(modelData.metadata));
        }

        // 添加明确的模型类型
        formData.append('modelType', 'external_model');

        // 添加格式信息确保后端能正确识别
        formData.append('format', modelData.format || file.name.split('.').pop());

        console.log('发送数据到服务器:', {
            modelDataKeys: Object.keys(modelData),
            hasMetadata: !!modelData.metadata,
            fileName: file.name,
            fileType: file.type,
            fileSize: file.size
        });

        const token = localStorage.getItem('token');
        try {
            const response = await axios.post(
                `${API_URL}/external/upload`,
                formData,
                {
                    headers: {
                        'Content-Type': 'multipart/form-data',
                        'Authorization': token ? `Bearer ${token}` : undefined
                    }
                }
            );
            return response;
        } catch (error) {
            // 添加详细日志便于调试
            console.error('API请求失败:', {
                status: error.response?.status,
                statusText: error.response?.statusText,
                data: error.response?.data,
                headers: error.response?.headers
            });
            throw error;
        }
    } catch (error) {
        console.error('一步创建和上传外部模型失败:', error);
        throw error.response?.data || error;
    }
};

// 更新外部模型属性
const updateExternalModel = async (modelId, updateData) => {
    try {
        if (useMockApi) {
            console.log('使用模拟API更新外部模型属性:', modelId, updateData);

            // 模拟延迟
            await new Promise(resolve => setTimeout(resolve, 500));

            // 返回模拟响应
            return {
                status: 200,
                data: {
                    status: 200,
                    message: '外部模型属性更新成功',
                    data: {
                        modelId: modelId,
                        updatedProps: Object.keys(updateData)
                    }
                }
            };
        }

        // 实际API调用
        const token = localStorage.getItem('token');
        const response = await axios.put(
            `${API_URL}/${modelId}/external-model`,
            updateData,
            {
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': token ? `Bearer ${token}` : undefined
                }
            }
        );

        return response;
    } catch (error) {
        console.error('更新外部模型属性失败:', error);
        throw error.response?.data || error;
    }
};

// 下载模型文件
const downloadModelFile = async (modelId, format = null) => {
    try {
        if (useMockApi) {
            console.log('使用模拟API下载模型文件:', modelId, format);

            // 模拟延迟
            await new Promise(resolve => setTimeout(resolve, 500));

            // 构造文件URL
            const fileExtension = format || 'glb';
            const fileName = `model_${modelId}.${fileExtension}`;
            const fileUrl = `http://localhost:3000/storage/models/${modelId}/${fileName}`;

            // 检查模拟存储中是否有此文件
            if (mockFileStorage.has(fileUrl)) {
                const fileData = mockFileStorage.get(fileUrl);
                console.log(`从模拟存储中获取文件: ${fileUrl}`);

                // 创建下载链接
                const link = document.createElement('a');
                link.href = fileData.data; // 使用存储的Data URL
                link.download = fileName;
                document.body.appendChild(link);
                link.click();

                // 清理
                setTimeout(() => {
                    document.body.removeChild(link);
                }, 100);

                return { success: true, fileName };
            }

            // 如果模拟存储中没有，创建一个空的文件
            console.log(`模拟存储中没有文件 ${fileUrl}，创建一个示例文件`);
            const dataUri = `data:model/${fileExtension};base64,`;

            const link = document.createElement('a');
            link.href = dataUri;
            link.download = fileName;
            document.body.appendChild(link);
            link.click();

            // 清理
            setTimeout(() => {
                document.body.removeChild(link);
            }, 100);

            return { success: true, fileName };
        }

        const url = format
            ? `${API_URL}/${modelId}/download?format=${format}`
            : `${API_URL}/${modelId}/download`;

        const response = await axios.get(url, {
            responseType: 'arraybuffer'
        });

        // 创建下载链接
        const fileExtension = format || 'glb';
        const fileName = `model_${modelId}.${fileExtension}`;

        // 确定MIME类型
        let mimeType;
        switch (fileExtension.toLowerCase()) {
            case 'obj':
                mimeType = 'application/x-tgif';
                break;
            case 'stl':
                mimeType = 'application/vnd.ms-pki.stl';
                break;
            case 'glb':
                mimeType = 'model/gltf-binary';
                break;
            case 'fbx':
                mimeType = 'application/octet-stream';
                break;
            default:
                mimeType = 'application/octet-stream';
        }

        // 将二进制数据转换为Base64
        const bytes = new Uint8Array(response.data);
        let binary = '';
        for (let i = 0; i < bytes.byteLength; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        const base64 = window.btoa(binary);

        // 创建数据URI
        const dataUri = `data:${mimeType};base64,${base64}`;

        // 创建下载链接并触发
        const link = document.createElement('a');
        link.href = dataUri;
        link.download = fileName;
        document.body.appendChild(link);
        link.click();

        // 清理
        setTimeout(() => {
            document.body.removeChild(link);
        }, 100);

        return { success: true, fileName };
    } catch (error) {
        console.error('下载模型文件失败:', error);
        throw error.response?.data || error;
    }
};

// 获取模型缩略图
const getModelThumbnail = async (modelId) => {
    try {
        if (useMockApi) {
            console.log('使用模拟API获取缩略图:', modelId);

            // 模拟延迟
            await new Promise(resolve => setTimeout(resolve, 500));

            // 返回一个占位缩略图URL
            return {
                success: true,
                thumbnailUrl: `http://localhost:3000/storage/thumbnails/${modelId}.jpg`,
                modelId: modelId
            };
        }

        const token = localStorage.getItem('token');
        const response = await axios.get(`${API_URL}/${modelId}/thumbnail`, {
            headers: {
                'Authorization': token ? `Bearer ${token}` : undefined
            }
        });
        return response.data;
    } catch (error) {
        console.error('获取模型缩略图失败:', error);
        throw error.response?.data || error;
    }
};

// 导入外部模型助手函数
const importExternalModel = async (file, modelData = {}) => {
    try {
        console.log('导入外部模型:', file.name, '类型:', modelData.format || file.name.split('.').pop());

        // 默认模型数据
        const defaultModelData = {
            name: file.name.split('.')[0] || '导入的模型',
            description: `导入的${modelData.format?.toUpperCase() || file.type || '外部'}模型`,
            color: modelData.color || '#3366FF',
            position: modelData.position || { x: 0, y: 0, z: 0 },
            rotation: modelData.rotation || { x: 0, y: 0, z: 0 },
            scale: modelData.scale || { x: 1, y: 1, z: 1 },
            format: file.name.split('.').pop().toLowerCase(), // 确保总是有格式
            type: 'external_model', // 确保设置类型
        };

        // 合并默认数据和用户提供的数据，确保保留元数据
        const mergedModelData = {
            ...defaultModelData,
            ...modelData,
            // 确保元数据被正确传递
            metadata: modelData.metadata || {
                originalType: 'external_model',
                externalId: modelData.externalId,
                cacheId: modelData.cacheId
            }
        };

        console.log('合并后的模型数据:', {
            name: mergedModelData.name,
            format: mergedModelData.format,
            hasMetadata: !!mergedModelData.metadata,
            metadataKeys: mergedModelData.metadata ? Object.keys(mergedModelData.metadata) : []
        });

        // 使用一步创建和上传方法
        const response = await createAndUploadExternalModel(mergedModelData, file);

        return response;
    } catch (error) {
        console.error('导入外部模型失败:', error);
        throw error;
    }
};

// 从服务器URL加载模型
const tryLoadModelFromServer = async (url) => {
    try {
        console.log('尝试从服务器URL加载模型:', url);

        // 从URL中提取模型ID
        let modelId = null;

        // 尝试从URL路径中提取ID
        const urlObj = new URL(url);
        const pathParts = urlObj.pathname.split('/');

        // 假设ID是路径中的最后一个或倒数第二个部分
        for (let i = pathParts.length - 1; i >= 0; i--) {
            if (pathParts[i] && pathParts[i] !== 'download' && pathParts[i] !== 'file') {
                modelId = pathParts[i];
                break;
            }
        }

        // 如果路径中没有找到，尝试从查询参数中提取
        if (!modelId) {
            modelId = urlObj.searchParams.get('id') ||
                urlObj.searchParams.get('modelId') ||
                urlObj.searchParams.get('model');
        }

        if (!modelId) {
            throw new Error('无法从URL中提取模型ID');
        }

        console.log('从URL中提取的模型ID:', modelId);

        // 使用模型ID获取模型数据
        // 这里假设有一个后端API用于获取模型信息
        if (useMockApi) {
            // 模拟获取模型数据
            await new Promise(resolve => setTimeout(resolve, 500));
            return {
                success: true,
                modelId: modelId,
                model: {
                    id: modelId,
                    name: '服务器模型',
                    description: '从服务器加载的模型',
                    geometry: {
                        type: 'external_model',
                        color: '#22AAFF',
                        file: 'server_model.glb',
                        fileUrl: url,
                        position: { x: 0, y: 0, z: 0 },
                        rotation: { x: 0, y: 0, z: 0 },
                        scale: { x: 1, y: 1, z: 1 }
                    }
                }
            };
        }

        // 实际实现时，这里应该调用API获取模型数据
        const token = localStorage.getItem('token');
        const response = await axios.get(`${API_URL}/${modelId}`, {
            headers: {
                'Authorization': token ? `Bearer ${token}` : undefined
            }
        });

        return {
            success: true,
            modelId: modelId,
            model: response.data
        };
    } catch (error) {
        console.error('从服务器URL加载模型失败:', error);
        throw error;
    }
};

// 导出文件处理服务和模拟存储(用于测试)
const fileService = {
    createExternalModel,
    uploadModelFile,
    downloadModelFile,
    getModelThumbnail,
    createAndUploadExternalModel,
    updateExternalModel,
    importExternalModel,
    tryLoadModelFromServer,
    mockFileStorage
};

export default fileService; 